#pragma once
#include <memory>
#include <map>
#include <mutex>
#include "Scenes.h"
#include "SqlTableOp.h"
#include "sqlite_orm.h"

namespace Media{

class ScenesManager{
public:
    using ScenesId = uint32_t;
    using Ptr = std::shared_ptr<ScenesManager>;

    static Ptr Instance();
    ScenesManager();
    ~ScenesManager();

    bool AddScenes(const std::string& scenesName, ScenesId& id, std::string& errinfo);
    bool DelScenes(ScenesId id);
    bool GetOneScenes(ScenesId id, Scenes::Ptr& scenes);
    bool GetAllScenes(std::map<ScenesId, Scenes::Ptr>& allScenes);

    //video item operate
    bool AddVideoInItem(ScenesId id, const VideoScenesInItemConfig& config, uint32_t& itemId);
    bool SetVideoInItem(ScenesId id, const VideoScenesInItemConfig& config, const uint32_t& itemId);
    bool DelVideoInItem(ScenesId id, const uint32_t& itemId);
    bool GetOneVideoInItem(ScenesId id, const uint32_t& itemId, VideoScenesInItemConfig& config);
    bool GetAllVideoInItem(ScenesId id,  std::map<Scenes::ItemId, VideoScenesInItemConfig>& items);


    bool SetVideoOutConfig(ScenesId id, const VideoScenesOutItemConfig& config);
    bool GetVideoOutConfig(ScenesId id, VideoScenesOutItemConfig& config);
    bool AddVideoOutSource(ScenesId id, uint32_t sourceId); 
    bool RemoveVideoOutSource(ScenesId id, uint32_t sourceId);
    
    
    //audio item operate
    bool AddAudioInItem(ScenesId id, const AudioScenesInItemConfig& config, uint32_t& itemId);
    bool SetAudioInItem(ScenesId id, const AudioScenesInItemConfig& config, const uint32_t& itemId);
    bool DelAudioInItem(ScenesId id, const uint32_t& itemId);
    bool GetOneAudioInItem(ScenesId id, const uint32_t& itemId, AudioScenesInItemConfig& config);
    bool GetAllAudioInItem(ScenesId id, std::map<Scenes::ItemId, AudioScenesInItemConfig> & items);

    bool SetAudioOutConfig(ScenesId id, const AudioScenesOutItemConfig& config);
    bool GetAudioOutConfig(ScenesId id, AudioScenesOutItemConfig& config);
    bool AddAudioOutSource(ScenesId id, uint32_t sourceId); 
    bool RemoveAudioOutSource(ScenesId id, uint32_t sourceId);


    bool SetFrameOutCb(ScenesId id, std::function<void (const FrameCommon::Frame::Ptr& frame)> cb);

    bool StartScenes(ScenesId id);
    bool StopScenes(ScenesId id);
private:
    bool init();

    std::recursive_mutex m_mux;
    ScenesId m_scenesIndex{};
    std::map<ScenesId, Scenes::Ptr> m_scenes;
    SqlTableOp::Ptr m_sql;

    #define LOCK_CHECK(id)  std::lock_guard<std::recursive_mutex> guard(m_mux);\
                            if(m_scenes.find(id) == m_scenes.end()){return false;}
};
}